package com.yql.commonextend.utils;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.yql.common.core.domain.entity.Order;
import com.yql.common.core.domain.request.OrderListReq;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.time.LocalDateTime;


public class Triple3DesUtils {


    public static void main(String[] args) {
        Triple3DesUtils des = new Triple3DesUtils();
//        des.key = "238EC4AECBF35BC3B8AC9ACD".getBytes();
//        des.ivs = "22345135".getBytes();
        //{"mobile":"15813331111","userId":"123","pageNum":1,"pageSize":1}
//        String str = "{\"mobile\":\"15813331111\",\"userId\":\"123\",\"pageNum\":1,\"pageSize\":1}";
        String str = "{\"commodityId\":\"2\",\"commodityCount\":\"10\"}";

//        OrderListReq order = new OrderListReq();
//        order.setBeginTime(LocalDateTime.now().plusDays(1));
//        order.setEndTime(LocalDateTime.now().plusDays(1));
//        String jsonStr = JSONUtil.toJsonStr(order);
//        System.out.println(jsonStr);
//        OrderListReq order1 = JSONUtil.toBean(jsonStr, OrderListReq.class);
//        System.out.println(order1);
//        String str = "{\"beginTime\":\"2021-12-24 12:00:00\",\"endTime\":\"2021-12-25 12:00:00\"}";
//        String str = "{\"beginTime\":1640406310451,\"endTime\":1640406310451}";
        String encrypt = des.TripleDesEncrypt(str, UTF8NAME);
        System.out.println(encrypt);
        String decrypt = des.TripleDesDecrypt(encrypt, UTF8NAME);
        System.out.println(decrypt);
//
//        OrderListReq order1 = JSONUtil.toBean(str, OrderListReq.class);
//        System.out.println(order1);
    }

    private static final Logger log = LoggerFactory.getLogger(Triple3DesUtils.class);

    private byte[] key = "UmOU4>?$a&#tuQ$NmP4CsQjO".getBytes();

    private byte[] ivs = "Foib@ZG*".getBytes();

    public static final String ISONAME = "ISO8859_1";

    public static final String GBKNAME = "GBK";

    public static final String UTF8NAME = "UTF-8";

    static {
        if (Security.getProvider("BC") == null)
            Security.addProvider((Provider) new BouncyCastleProvider());
    }

    public Triple3DesUtils() {}


    public Triple3DesUtils(String key, String ivs) {
        if (key != null && ivs != null) {
            if (key.length() > 24)
                key = key.substring(0, 24);
            this.key = key.getBytes();
            if (ivs.length() > 8)
                ivs = ivs.substring(0, 8);
            this.ivs = ivs.getBytes();
        }
    }

    public void setKey(String key) {
        if (key != null) {
            if (key.length() > 24)
                key = key.substring(0, 24);
            this.key = key.getBytes();
        }
    }

    public void setIvs(String ivs) {
        if (ivs != null) {
            if (ivs.length() > 8)
                ivs = ivs.substring(0, 8);
            this.ivs = ivs.getBytes();
        }
    }

    /**
     * 加密
     *
     * @param srcStr   需要加密的字符串
     * @param codeName 编码
     * @return
     */
    public String TripleDesEncrypt(String srcStr, String codeName) {
        SecretKeySpec desKey = new SecretKeySpec(this.key, "DESede");
        IvParameterSpec iv = new IvParameterSpec(this.ivs);
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("DESede/CBC/PKCS7Padding", "BC");
        } catch (Exception e) {
            log.error("TripleDesEncrypt方法异常01", e);
        }
        try {
            cipher.init(1, desKey, iv);
        } catch (Exception e) {
            log.error("TripleDesEncrypt方法异常02", e);
        }
        byte[] cipherText = (byte[]) null;
        try {
            cipherText = cipher.doFinal(srcStr.getBytes(codeName));
        } catch (Exception e) {
            log.error("TripleDesEncrypt方法异常03", e);
        }
        return new String(Base64.encode(cipherText));
    }

    /**
     * 解密
     *
     * @param srcStr   需要解密的字符串
     * @param codeName 编码
     * @return
     */
    public String TripleDesDecrypt(String srcStr, String codeName) {
        SecretKeySpec desKey = new SecretKeySpec(this.key, "DESede");
        IvParameterSpec iv = new IvParameterSpec(this.ivs);
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("DESede/CBC/PKCS7Padding", "BC");
        } catch (Exception e) {
            log.error("TripleDesDecrypt方法异常01", e);
        }
        try {
            cipher.init(2, desKey, iv);
        } catch (Exception e) {
            log.error("TripleDesEncrypt方法异常02", e);
        }
        byte[] cipherText = (byte[]) null;
        try {
            cipherText = cipher.doFinal(Base64.decode(srcStr));
        } catch (Exception e) {
            log.error("TripleDesEncrypt方法异常03", e);
        }
        try {
            return new String(cipherText, codeName);
        } catch (UnsupportedEncodingException e) {
            log.error("TripleDesEncrypt方法异常04", e);;
            return null;
        }
    }

    /**
     * 加密
     *
     * @param srcStr
     * @param codeName
     * @return
     */
    public String TripleDesEncryptToHex(String srcStr, String codeName) {
        SecretKeySpec desKey = new SecretKeySpec(this.key, "DESede");
        IvParameterSpec iv = new IvParameterSpec(this.ivs);
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("DESede/CBC/PKCS7Padding", "BC");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            cipher.init(1, desKey, iv);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        byte[] cipherText = (byte[]) null;
        try {
            cipherText = cipher.doFinal(srcStr.getBytes(codeName));
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bytesToHex(cipherText);
    }


    /**
     * 字节数组转16进制
     *
     * @param bArr 需要转换的byte数组
     * @return 转换后的Hex字符串
     */
    public String bytesToHex(byte[] bArr){
        StringBuffer stringBuffer = new StringBuffer(bArr.length);
        String sTmp;
        for (int i = 0; i < bArr.length; i++) {
            sTmp = Integer.toHexString(0xFF & bArr[i]);
            if(sTmp.length() < 2){
                stringBuffer.append(0);
            }
            stringBuffer.append(sTmp.toUpperCase());
        }
        return stringBuffer.toString();
    }
}
